register.js ➔ ???   B
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 15
Bugs 0 Features 0
Metric Value
cc 2
c 15
b 0
f 0
nc 1
nop 3
dl 0
loc 24
rs 8.9713
1
const defaultCommandOptions = require('./util/DefaultCommandOptions')
2
/**
3
 * A register, to add commands to fisherman extending the Map class
4
 * The commands added are storen directly in the map
5
 * @class FisherRegister
6
 * @extends {Map}
7
 */
8
class FisherRegister extends Map {
9
    /**
10
     * Creates an instance of FisherRegister.
11
     * @param {Fisherman} client
12
     * @param {string} [name = null]
0 ignored issues
show
Documentation Bug introduced by
The parameter [name does not exist. Did you maybe mean name instead?
Loading history...
13
     * @param {string} [desc = null]
0 ignored issues
show
Documentation Bug introduced by
The parameter [desc does not exist. Did you maybe mean desc instead?
Loading history...
14
     * @memberof FisherRegister
15
     */
16
  constructor (client, name = null, desc = null) {
17
    super()
18
    if (!client) throw new TypeError('Client not defined')
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
19
      /**
20
       * The fisherman client that instantied the register
21
       * @name FisherRegister#client
22
       * @type {Fisherman}
23
       */
24
    this.client = client
25
        /**
26
         * The register description, used by commands, like "help"
27
         * @name FisherRegister#description
28
         * @type {string}
29
         * @default null
30
         */
31
    this.description = desc
32
        /**
33
         * The register name, used by commands, like "help"
34
         * @name FisherRegister#name
35
         * @type {string}
36
         * @default null
37
         */
38
    this.name = name
39
  }
40
    /**
41
     * A text command that can be only executed in a guild
42
     * @example textCommand("cat", null, function(req,res) {});
43
     * @param {string} name The command's name
44
     * @param {DefaultCommandOptions} [options = {} ] An option object, that will be asigned with defaultCommandOptions
0 ignored issues
show
Documentation Bug introduced by
The parameter [options does not exist. Did you maybe mean options instead?
Loading history...
45
     * @param {FisherCallback} callback A FisherCallback
46
     * @return {FisherRegister} Return the current register
47
     */
48
  textCommand (name, options, callback) {
49
    if (typeof callback !== 'function') { throw new TypeError('Callback must be a function') }
50
    if (typeof name !== 'string') {
51
      throw new TypeError('Command name must be a string')
52
    }
53
    var cmd = Object.create(defaultCommandOptions)
54
    cmd.register = this
55
    cmd.channelType = 'text'
56
    cmd.execute = callback.bind(cmd)
57
    cmd.name = name
58
    cmd = Object.assign(cmd, options)
59
    this.set(name, cmd)
60
    return this
61
  }
62
    /**
63
     * A command, specified by the name and the scope.
64
     * @example command(["dm", "text"], "cat", null, function(req, res){});
65
     * @param {(string[]|string)} scope The channel type, can be an array or a string
66
     * @param {string} name The command's name
67
     * @param {DefaultCommandOptions} [options = {}] An option object, that will be asigned with DefaultCommandOptions
0 ignored issues
show
Documentation Bug introduced by
The parameter [options does not exist. Did you maybe mean options instead?
Loading history...
68
     * @param {FisherCallback} callback A FisherCallback
69
     * @return {FisherRegister} Return the current register
70
     * @memberof FisherRegister
71
     */
72 View Code Duplication
  command (scope, name, options, callback) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
73
    if (!Array.isArray(scope) || !(typeof scope === 'string')) { throw new TypeError('scope must be a string or an array') }
74
    if (typeof callback !== 'function' || typeof name !== 'string') { throw new TypeError('Callback must be a function, command name must be a string') }
75
76
    var cmd = Object.create(defaultCommandOptions)
77
    cmd.register = this
78
    cmd.channelType = scope
79
    cmd.execute = callback.bind(cmd)
80
    cmd.name = name
81
    cmd = Object.assign(cmd, options)
82
    this.set(name, cmd)
83
    return this
84
  }
85
  /**
86
   * A command, that can be resolved/rejected. It triggers fishercodes when it's resolved/rejected
87
   * @example command(["dm", "text"], "cat", null, function(req, res, resolve, reject){});
88
   * @param {(string[]|string)} scope The channel type, can be an array or a string
89
   * @param {string} name The command's name
90
   * @param {DefaultCommandOptions} [options = {}] An option object, that will be asigned with DefaultCommandOptions
0 ignored issues
show
Documentation Bug introduced by
The parameter [options does not exist. Did you maybe mean options instead?
Loading history...
91
   * @param {FisherPromiseCallback} callback A FisherPromiseCallback
92
   * @return {FisherRegister} Return the current register
93
   * @memberof FisherRegister
94
   */
95 View Code Duplication
  promiseCommand (scope, name, options, callback) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
96
    if (!(Array.isArray(scope) || typeof scope === 'string')) { throw new TypeError('scope must be a string or an array') }
97
    if (typeof callback !== 'function' || typeof name !== 'string') { throw new TypeError('Callback must be a function, command name must be a string') }
98
    var cmd = Object.create(defaultCommandOptions)
99
    cmd.register = this
100
    cmd.isPromise = true
101
    cmd.channelType = scope
102
    cmd.execute = callback.bind(cmd)
103
    cmd.name = name
104
    cmd = Object.assign(cmd, options)
105
    this.set(name, cmd)
106
    return this
107
  }
108
    /**
109
     * Add a command to fisherman, through an object or an command class extending the abstract class "Command"
110
     * @param {(Object|Command)} command An object, or a class extending the abstract class "Command"
111
     * @memberof FisherRegister
112
     */
113
  addCommand (command) {
114
    var cmd = Object.assign(Object.create(defaultCommandOptions), command)
115
    this.set(cmd.name, cmd)
116
  }
117
  set (key, value) {
118
    /**
119
     * Emitted when a new command is added
120
     * @event Fisherman#commandAdded
121
     * @param {Command}
122
     */
123
    super.set(key, value)
124
    this.client.commands.set(key, value)
125
    this.client.emit('commandAdded', value)
126
    this.setAliases(key, value)
127
  }
128
    /**
129
     * set the aliases for the fisher client
130
     * @private
131
     * @param {string} key
132
     * @param {Object} value
133
     * @memberof FisherRegister
134
     */
135
  setAliases (key, value) {
136
    if (typeof value.aliases === 'string') {
137
      this.client.aliases.set(value.aliases, value)
138
      this.client.commands.set(value.aliases, value)
139
    } else if (Array.isArray(value.aliases)) {
140
      var i
141
      for (i in value.aliases) {
142
        this.client.aliases.set(value.aliases[i], value)
143
        this.client.commands.set(value.aliases[i], value)
144
      }
145
    }
146
  }
147
    /**
148
     * delete the aliases for the given command/key
149
     * @private
150
     * @param {string} key
151
     * @memberof FisherRegister
152
     */
153
  clearAliases (key) {
154
    var cmd = super.get(key)
155
    if (cmd) {
156
      if (typeof cmd.aliases === 'string') {
157
        this.client.aliases.delete(cmd.aliases)
158
        this.client.commands.delete(cmd.aliases)
159
      } else if (Array.isArray(cmd.aliases)) {
160
        var i
161
        for (i in cmd.aliases) {
162
          this.client.aliases.delete(cmd.aliases[i])
163
          this.client.commands.delete(cmd.aliases[i])
164
        }
165
      }
166
    }
167
  }
168
  delete (key) {
169
    this.clearAliases(key)
170
    super.delete(key)
171
    this.client.commands.delete(key)
172
  }
173
}
174
module.exports = FisherRegister
175
/**
176
 * @typedef {function} FisherCallback The command's execution function
177
 * @param {FisherRequest} req A request object
178
 * @param {FisherResponse} res A response object
179
 */
180
/**
181
 * @typedef {function} FisherPromiseCallback The promise command's execution function with a promise callback
182
 * @param {FisherRequest} req A request object
183
 * @param {FisherResponse} res A response object
184
 * @param {function} resolve A promise resolve function
185
 * @param {function} reject A promise reject function
186
 */
187